home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / formwin.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  42KB  |  1,171 lines

  1. /*
  2.  * Create the form edit window and the form edit canvas window.
  3.  *
  4.  *    create_formedit_window        Create form edit window and realize
  5.  *    fillout_formedit_widget_by_code    Redraw single item
  6.  */
  7.  
  8. #include "config.h"
  9. #include <X11/Xos.h>
  10. #include <stdlib.h>
  11. #include <Xm/Xm.h>
  12. #include <Xm/MainW.h>
  13. #include <Xm/Form.h>
  14. #include <Xm/Frame.h>
  15. #include <Xm/LabelP.h>
  16. #include <Xm/PushBP.h>
  17. #include <Xm/PushBG.h>
  18. #include <Xm/ToggleB.h>
  19. #include <Xm/Text.h>
  20. #include <Xm/Separator.h>
  21. #include <Xm/RowColumn.h>
  22. #include <Xm/ScrolledW.h>
  23. #include <Xm/Protocols.h>
  24. #include <X11/cursorfont.h>
  25. #include "grok.h"
  26. #include "form.h"
  27. #include "proto.h"
  28.  
  29. static void formedit_callback(Widget, int, XmToggleButtonCallbackStruct *);
  30. static int readback_item(int);
  31.  
  32. extern Display        *display;    /* everybody uses the same server */
  33. extern GC        gc;        /* everybody uses this context */
  34. extern struct config    config;        /* global configuration data */
  35. extern CARD         *curr_card;    /* card being displayed in main win */
  36. extern Pixel        color[NCOLS];    /* colors: COL_* */
  37. extern XFontStruct    *font[NFONTS];    /* fonts: FONT_* */
  38. extern XmFontList    fontlist[NFONTS];
  39.  
  40. static BOOL        have_shell;    /* message popup exists if TRUE */
  41. static Widget        shell;        /* popup menu shell */
  42. static BOOL        external_form;    /* got form from caller,don't destroy*/
  43. static FORM        *form;        /* current form definition */
  44. int            curr_item;    /* current item, 0..form.nitems-1 */
  45.  
  46.  
  47. #define ANY 0xfffe
  48. #define ITX 1<<IT_INPUT  | 1<<IT_TIME | 1<<IT_NOTE
  49. #define TXT 1<<IT_PRINT  | ITX
  50. #define TXF 1<<IT_CHOICE | TXT
  51. #define FLG 1<<IT_CHOICE | 1<<IT_FLAG
  52. #define BAS ITX | FLG
  53. #define TIM 1<<IT_TIME
  54. #define BUT 1<<IT_BUTTON
  55. #define VIW 1<<IT_VIEW
  56. #define CHA 1<<IT_CHART
  57.  
  58. /*
  59.  * next free: 108-10a,114 (global), 237 (field), 30b (chart component)
  60.  */
  61.  
  62. static struct _template {
  63.     unsigned
  64.     short    sensitive;    /* when type is n, make sensitive if & 1<<n */
  65.     int    type;        /* Text, Label, Rradio, Fflag, -line */
  66.     int    code;        /* code given to (global) callback routine */
  67.     char    *text;        /* label string */
  68.     char    *help;        /* label string */
  69.     Widget    widget;        /* allocated widget */
  70. } template[] = {
  71.     {  ~0, 'L',     0,    "Form name:",        "fe_form",    },
  72.     {  ~0, 'T',    0x101,    " ",            "fe_form",    },
  73.     {  ~0, 'L',     0,    "Referenced database:",    "fe_form",    },
  74.     {  ~0, 'T',    0x102,    " ",            "fe_form",    },
  75.     {  ~0, 'L',     0,    "dbase field delim:",    "fe_delim",    },
  76.     {  ~0, 't',    0x103,    " ",            "fe_delim",    },
  77.     {   0, 'F',     0,    " ",            0,        },
  78.     {  ~0, 'f',    0x104,    "Read only",        "fe_rdonly",    },
  79.     {  ~0, 'f',    0x105,    "procedural",        "fe_proc",    },
  80.     {  ~0, 'B',    0x106,    "Edit",            "fe_proc",    },
  81.     {  ~0, 'L',     0,    "Comment:",        "fe_ref",    },
  82.     {  ~0, 'T',    0x107,    " ",            "fe_ref",    },
  83.  
  84.     {  ~0, 'L',     0,    "Form",            0,        },
  85.     {  ~0, 'B',    0x10c,    "Queries",        "fe_query",    },
  86.     {  ~0, 'B',    0x10b,    "Def Help",        "fe_defhelp",    },
  87.     {  ~0, 'B',    0x10d,    "Debug",        "fe_debug",    },
  88.     {  ~0, 'B',    0x10e,    "Preview",        "fe_preview",    },
  89.     {  ~0, 'B',    0x10f,    "Help",            "edit",        },
  90.     {  ~0, 'B',    0x110,    "Cancel",        "fe_cancel",    },
  91.     {  ~0, 'B',    0x111,    "Done",            "fe_done",    },
  92.     {   0, '-',     0,    " ",            0,        },
  93.     {  ~0, 'L',     0,    "Field",        "fe_buts",    },
  94.     {  ~0, 'B',    0x112,    "Add",            "fe_add",    },
  95.     { ANY, 'B',    0x113,    "Delete",        "fe_delete",    },
  96.     {   0, '[',     0,    "attrs",        0,        },
  97.  
  98.     { ANY, 'L',     0,       "Field type:",    "fe_type",    },
  99.     {   0, 'R',     0,       " ",            0,        },
  100.     { ANY, 'r',    IT_INPUT,  "Input",        "fe_type",    },
  101.     { ANY, 'r',    IT_TIME,   "Time",        "fe_type",    },
  102.     { ANY, 'r',    IT_NOTE,   "Note",        "fe_type",    },
  103.     { ANY, 'r',    IT_LABEL,  "Label",        "fe_type",    },
  104.     { ANY, 'r',    IT_PRINT,  "Print",        "fe_type",    },
  105.     { ANY, 'r',    IT_CHOICE, "Choice",        "fe_type",    },
  106.     { ANY, 'r',    IT_FLAG,   "Flag",        "fe_type",    },
  107.     { ANY, 'r',    IT_BUTTON, "Button",        "fe_type",    },
  108.     { ANY, 'r',    IT_CHART,  "Chart",        "fe_type",    },
  109. #if 0
  110.     { ANY, 'r',    IT_VIEW,   "View",        "fe_type",    },
  111. #endif
  112.     { ANY, 'L',     0,    "Flags:",        "fe_flags",    },
  113.     {   0, 'F',     0,    " ",            0,        },
  114.     { BAS, 'f',    0x200,    "Searchable",        "fe_flags",    },
  115.     { BAS, 'f',    0x201,    "Read only",        "fe_flags",    },
  116.     { BAS, 'f',    0x202,    "Not sortable",        "fe_flags",    },
  117.     { BAS, 'f',    0x203,    "Default sort",        "fe_flags",    },
  118.     { ANY, 'L',     0,    "Internal field name:",    "fe_int",    },
  119.     { ANY, 't',    0x204,    " ",            "fe_int",    },
  120.     { BAS, 'L',     0,    "Database column:",    "fe_column",    },
  121.     { BAS, 't',    0x205,    " ",            "fe_column",    },
  122.     { BAS, 'L',     0,    "Summary column:",    "fe_sum",    },
  123.     { BAS, 't',    0x206,    " ",            "fe_sum",    },
  124.     { BAS, 'l',     0,    "Width in summary:",    "fe_sum",    },
  125.     { BAS, 't',    0x207,    " ",            "fe_sum",    },
  126.     { FLG, 'L',     0,    "Choice/flag code:",    "fe_flag",    },
  127.     { FLG, 't',    0x208,    " ",            "fe_flag",    },
  128.     { FLG, 'l',     0,    "shown in summary as",    "fe_flag",    },
  129.     { FLG, 't',    0x236,    " ",            "fe_flag",    },
  130.     { TIM, 'L',     0,    "Time format:",        "fe_time",    },
  131.     {   0, 'R',     0,    " ",            0,        },
  132.     { TIM, 'r',    0x209,    "Date",            "fe_time",    },
  133.     { TIM, 'r',    0x20a,    "Time",            "fe_time",    },
  134.     { TIM, 'r',    0x20b,    "Date+time",        "fe_time",    },
  135.     { TIM, 'r',    0x20c,    "Duration",        "fe_time",    },
  136.     {   0, '-',     0,    " ",            0,        },
  137.  
  138.     { ANY, 'L',     0,    "Label Justification:",    "fe_ljust",    },
  139.     {   0, 'R',     0,    " ",            0,        },
  140.     { ANY, 'r',    0x20d,    "left",            "fe_ljust",    },
  141.     { ANY, 'r',    0x20e,    "center",        "fe_ljust",    },
  142.     { ANY, 'r',    0x20f,    "right",        "fe_ljust",    },
  143.     { ANY, 'L',     0,    "Label font:",        "fe_ljust",    },
  144.     {   0, 'R',     0,    " ",            0,        },
  145.     { ANY, 'r',    0x210,    "Helv",            "fe_lfont",    },
  146.     { ANY, 'r',    0x211,    "HelvO",        "fe_lfont",    },
  147.     { ANY, 'r',    0x212,    "HelvN",        "fe_lfont",    },
  148.     { ANY, 'r',    0x213,    "HelvB",        "fe_lfont",    },
  149.     { ANY, 'r',    0x214,    "Courier",        "fe_lfont",    },
  150.     { ANY, 'L',     0,    "Label text",        "fe_ltxt",    },
  151.     { ANY, 'T',    0x21a,    " ",            "fe_ltxt",    },
  152.     {   0, '-',     0,    " ",            0,        },
  153.  
  154.     { TXT, 'L',     0,    "Input Justification:",    "fe_ijust",    },
  155.     {   0, 'R',     0,    " ",            0,        },
  156.     { TXT, 'r',    0x21b,    "left",            "fe_ijust",    },
  157.     { TXT, 'r',    0x21c,    "center",        "fe_ijust",    },
  158.     { TXT, 'r',    0x21d,    "right",        "fe_ijust",    },
  159.     { TXT, 'L',     0,    "Input font:",        "fe_ijust",    },
  160.     {   0, 'R',     0,    " ",            0,        },
  161.     { TXT, 'r',    0x215,    "Helv",            "fe_ifont",    },
  162.     { TXT, 'r',    0x216,    "HelvO",        "fe_ifont",    },
  163.     { TXT, 'r',    0x217,    "HelvN",        "fe_ifont",    },
  164.     { TXT, 'r',    0x218,    "HelvB",        "fe_ifont",    },
  165.     { TXT, 'r',    0x219,    "Courier",        "fe_ifont",    },
  166.     { ITX, 'L',     0,    "Max input length:",    "fe_range",    },
  167. #if 0
  168.     { ITX, 't',    0x21e,    " ",            "fe_range",    },
  169. #endif
  170.     { ITX, 't',    0x21f,    " ",            "fe_range",    },
  171.     { TXF, 'L',     0,    "Input default:",    "fe_def",    },
  172.     { TXF, 'T',    0x220,    " ",            "fe_def",    },
  173. #if 0
  174.     { ITX, 'L',     0,    "Input pattern:",    "fe_pattern",    },
  175.     { ITX, 'T',    0x221,    " ",            "fe_pattern",    },
  176. #endif
  177.     {   0, '-',     0,    " ",            0,        },
  178.  
  179.     { ANY, 'L',     0,    "Grayed out if:",    "fe_gray",    },
  180.     { ANY, 'T',    0x222,    " ",            "fe_gray",    },
  181.     { ANY, 'L',     0,    "Invisible if:",    "fe_inv",    },
  182.     { ANY, 'T',    0x223,    " ",            "fe_inv",    },
  183.     { ANY, 'L',     0,    "Read-only if:",    "fe_ro",    },
  184.     { ANY, 'T',    0x224,    " ",            "fe_ro",    },
  185.     { ANY, 'L',     0,    "Skip if:",        "fe_skip",    },
  186.     { ANY, 'T',    0x225,    " ",            "fe_skip",    },
  187.     {   0, '-',     0,    " ",            0,        },
  188.  
  189.     { BUT, 'L',     0,    "Action when pressed:",    "fe_press",    },
  190.     { BUT, 'T',    0x226,    " ",            "fe_press",    },
  191.     { BUT, 'L',     0,    "Action when added:",    "fe_add",    },
  192.     { BUT, 'T',    0x227,    " ",            "fe_add",    },
  193.     {   0, '-',     0,    " ",            0,        },
  194.  
  195.     { CHA, 'L',     0,    "Chart X range:",    "fe_chart",    },
  196.     { CHA, 't',    0x280,    " ",            "fe_chart",    },
  197.     { CHA, 'l',     0,    "to",            "fe_chart",    },
  198.     { CHA, 't',    0x281,    " ",            "fe_chart",    },
  199.     { CHA, 'F',     0,     " ",            0,        },
  200.     { CHA, 'f',    0x28c,    "automatic",        "fe_chart",    },
  201.     { CHA, 'L',     0,    "Chart Y range:",    "fe_chart",    },
  202.     { CHA, 't',    0x282,    " ",            "fe_chart",    },
  203.     { CHA, 'l',     0,    "to",            "fe_chart",    },
  204.     { CHA, 't',    0x283,    " ",            "fe_chart",    },
  205.     { CHA, 'F',     0,     " ",            0,        },
  206.     { CHA, 'f',    0x28d,    "automatic",        "fe_chart",    },
  207.     { CHA, 'L',     0,    "Chart XY grid every:",    "fe_chart",    },
  208.     { CHA, 't',    0x284,    " ",            "fe_chart",    },
  209.     { CHA, 't',    0x285,    " ",            "fe_chart",    },
  210.     { CHA, 'L',     0,    "Chart XY snap every:",    "fe_chart",    },
  211.     { CHA, 't',    0x286,    " ",            "fe_chart",    },
  212.     { CHA, 't',    0x287,    " ",            "fe_chart",    },
  213. /*    { CHA, 'L',     0,    "Chart X label every:",    "fe_chart",    },
  214.     { CHA, 't',    0x288,    " ",            "fe_chart",    },
  215.     { CHA, 'l',     0,    "text:",        "fe_chart",    },
  216.     { CHA, 'T',    0x289,    " ",            "fe_chart",    },
  217.     { CHA, 'L',     0,    "Chart Y label every:",    "fe_chart",    },
  218.     { CHA, 't',    0x28a,    " ",            "fe_chart",    },
  219.     { CHA, 'l',     0,    "text:",        "fe_chart",    },
  220.     { CHA, 'T',    0x28b,    " ",            "fe_chart",    }, */
  221.     { CHA, 'L',     0,    "Chart component:",    0,        },
  222.     { CHA, 'B',    0x290,    "Add",            "fe_chart",    },
  223.     { CHA, 'B',    0x291,    "Delete",        "fe_chart",    },
  224.     { CHA, 'l',    0x294,    "none",            "fe_chart",    },
  225.     { CHA, 'B',    0x293,    "Next",            "fe_chart",    },
  226.     { CHA, 'B',    0x292,    "Previous",        "fe_chart",    },
  227.  
  228.     {   0, '{',     0,    "comps",        0,        },
  229.     { CHA, 'L',     0,     "Component flags",    "fe_chart",    },
  230.     { CHA, 'F',     0,     " ",            0,        },
  231.     { CHA, 'f',    0x301,    "Line",            "fe_chart",    },
  232.     { CHA, 'f',    0x302,    "X fat",        "fe_chart",    },
  233.     { CHA, 'f',    0x303,    "Y fat",        "fe_chart",    },
  234.     { CHA, 'L',     0,    "Exclude if:",        "fe_chart",    },
  235.     { CHA, 'T',    0x304,    " ",            "fe_chart",    },
  236.     { CHA, 'L',     0,    "Color 0..7:",        "fe_chart",    },
  237.     { CHA, 'T',    0x305,    " ",            "fe_chart",    },
  238.     { CHA, 'L',     0,    "Label:",        "fe_chart",    },
  239.     { CHA, 'T',    0x306,    " ",            "fe_chart",    },
  240.  
  241.     { CHA, 'L',     0,    "X position:",        "fe_chart",    },
  242.     {   0, 'R',     0,    " ",            0,        },
  243.     { CHA, 'r',    0x310,    "next free",        "fe_chart",    },
  244.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  245.     {   0, 'R',     0,    " ",            0,        },
  246.     { CHA, 'r',    0x311,    "same as previous",    "fe_chart",    },
  247.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  248.     {   0, 'R',     0,    " ",            0,        },
  249.     { CHA, 'r',    0x312,    "expression",        "fe_chart",    },
  250.     { CHA, 'T',    0x314,    " ",            "fe_chart",    },
  251.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  252.     {   0, 'R',     0,    " ",            0,        },
  253.     { CHA, 'r',    0x313,    "drag field",        "fe_chart",    },
  254.     { CHA, 't',    0x315,    " ",            "fe_chart",    },
  255.     { CHA, 'l',     0,    "multiplied by",    "fe_chart",    },
  256.     { CHA, 't',    0x316,    " ",            "fe_chart",    },
  257.     { CHA, 'l',     0,    "plus",            "fe_chart",    },
  258.     { CHA, 't',    0x317,    " ",            "fe_chart",    },
  259.  
  260.     { CHA, 'L',     0,    "Y position:",        "fe_chart",    },
  261.     {   0, 'R',     0,    " ",            0,        },
  262.     { CHA, 'r',    0x320,    "next free",        "fe_chart",    },
  263.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  264.     {   0, 'R',     0,    " ",            0,        },
  265.     { CHA, 'r',    0x321,    "same as previous",    "fe_chart",    },
  266.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  267.     {   0, 'R',     0,    " ",            0,        },
  268.     { CHA, 'r',    0x322,    "expression",        "fe_chart",    },
  269.     { CHA, 'T',    0x324,    " ",            "fe_chart",    },
  270.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  271.     {   0, 'R',     0,    " ",            0,        },
  272.     { CHA, 'r',    0x323,    "drag field",        "fe_chart",    },
  273.     { CHA, 't',    0x325,    " ",            "fe_chart",    },
  274.     { CHA, 'l',     0,    "multiplied by",    "fe_chart",    },
  275.     { CHA, 't',    0x326,    " ",            "fe_chart",    },
  276.     { CHA, 'l',     0,    "plus",            "fe_chart",    },
  277.     { CHA, 't',    0x327,    " ",            "fe_chart",    },
  278.  
  279.     { CHA, 'L',     0,    "X size:",        "fe_chart",    },
  280. /*    {   0, 'R',     0,    " ",            0,        },
  281.     { CHA, 'r',    0x330,    "next free",        "fe_chart",    },
  282.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  283.     {   0, 'R',     0,    " ",            0,        },
  284.     { CHA, 'r',    0x331,    "same as previous",    "fe_chart",    },
  285.     { CHA, 'L',     0,    " ",            "fe_chart",    }, */
  286.     {   0, 'R',     0,    " ",            0,        },
  287.     { CHA, 'r',    0x332,    "expression",        "fe_chart",    },
  288.     { CHA, 'T',    0x334,    " ",            "fe_chart",    },
  289. /*    { CHA, 'L',     0,    " ",            "fe_chart",    },
  290.     {   0, 'R',     0,    " ",            0,        },
  291.     { CHA, 'r',    0x333,    "drag field",        "fe_chart",    },
  292.     { CHA, 't',    0x335,    " ",            "fe_chart",    },
  293.     { CHA, 'l',     0,    "multiplied by",    "fe_chart",    },
  294.     { CHA, 't',    0x336,    " ",            "fe_chart",    },
  295.     { CHA, 'l',     0,    "plus",            "fe_chart",    },
  296.     { CHA, 't',    0x337,    " ",            "fe_chart",    }, */
  297.  
  298.     { CHA, 'L',     0,    "Y size:",        "fe_chart",    },
  299. /*    {   0, 'R',     0,    " ",            0,        },
  300.     { CHA, 'r',    0x340,    "next free",        "fe_chart",    },
  301.     { CHA, 'L',     0,    " ",            "fe_chart",    },
  302.     {   0, 'R',     0,    " ",            0,        },
  303.     { CHA, 'r',    0x341,    "same as previous",    "fe_chart",    },
  304.     { CHA, 'L',     0,    " ",            "fe_chart",    }, */
  305.     {   0, 'R',     0,    " ",            0,        },
  306.     { CHA, 'r',    0x342,    "expression",        "fe_chart",    },
  307.     { CHA, 'T',    0x344,    " ",            "fe_chart",    },
  308. /*    { CHA, 'L',     0,    " ",            "fe_chart",    },
  309.     {   0, 'R',     0,    " ",            0,        },
  310.     { CHA, 'r',    0x343,    "drag field",        "fe_chart",    },
  311.     { CHA, 't',    0x345,    " ",            "fe_chart",    },
  312.     { CHA, 'l',     0,    "multiplied by",    "fe_chart",    },
  313.     { CHA, 't',    0x346,    " ",            "fe_chart",    },
  314.     { CHA, 'l',     0,    "plus",            "fe_chart",    },
  315.     { CHA, 't',    0x347,    " ",            "fe_chart",    }, */
  316.  
  317.     {   0, '}',     0,    " ",            0,        },
  318. #if 0
  319.     {   0, '-',     0,    " ",            0,        },
  320.  
  321.     { VIW, 'L',     0,    "Show query result as:","fe_result",    },
  322.     {   0, 'F',     0,    " ",            0,        },
  323.     { VIW, 'f',    0x231,    "Summary:",        "fe_result",    },
  324.     { VIW, 'f',    0x232,    "first card:",        "fe_result",    },
  325.     { VIW, 'f',    0x233,    "last card:",        "fe_result",    },
  326.     { VIW, 'L',     0,    "Database:",        "fe_query",    },
  327.     { VIW, 'T',    0x234,    " ",            "fe_query",    },
  328.     { VIW, 'L',     0,    "Query:",        "fe_query",    },
  329.     { VIW, 'T',    0x235,    " ",            "fe_query",    },
  330. #endif
  331.  
  332.     {   0, ']',     0,    " ",            0,        },
  333.     {   0,  0,     0,    0,            0        },
  334. };
  335.  
  336.  
  337. /*-------------------------------------------------- create window ----------*/
  338. /*
  339.  * destroy form edit shell and remove it from the screen. If the form being
  340.  * edited was created by create_formedit_window(), destroy it; otherwise
  341.  * leave it intact and display it in the main window (using switch_form()).
  342.  */
  343.  
  344. void destroy_formedit_window(void)
  345. {
  346.     if (have_shell) {
  347.         XtPopdown(shell);
  348.         XtDestroyWidget(shell);
  349.         have_shell = FALSE;
  350.     }
  351. }
  352.  
  353.  
  354. /*
  355.  * create form edit shell and all the buttons in it, but don't fill in
  356.  * any data yet. If <def> is nonzero, edit the form <def> (the one currently
  357.  * being displayed in the main window); if <def> is zero, start a new form.
  358.  * If <copy> is TRUE, don't use <def> directly, create a copy by changing
  359.  * form name to something that won't overwrite the original.
  360.  */
  361.  
  362. void create_formedit_window(
  363.     FORM            *def,        /* new form to edit */
  364.     BOOL            copy,        /* use a copy of <def> */
  365.     BOOL            new)        /* ok to change form name */
  366. {
  367.     struct _template    *tp;
  368.     int            len;        /* width of first column */
  369.     WidgetClass        class;
  370.     String            cback;
  371.     Widget            cform, outerform=0, innerform=0;
  372.     Widget            scroll=0, chart=0;
  373.     Widget            top, left, prev=0, prevline=0;
  374.     Arg            args[30];
  375.     long            t, n;
  376.     Atom            closewindow;
  377.  
  378.     if (def && have_shell && def == form)        /* same as before */
  379.         return;
  380.     external_form = def != 0;
  381.     if (!def)
  382.         form = form_create();
  383.     else {
  384.         form = form_clone(def);
  385.         if (copy) {
  386.             if (form->name)  free(form->name);
  387.             form->name = 0;
  388.         }
  389.     }
  390.     if (new && form->path) {
  391.         free(form->path);
  392.         form->path = 0;
  393.     }
  394.     create_canvas_window(form);            /* canvas window */
  395.     if (have_shell) {
  396.         sensitize_formedit();            /* re-use window */
  397.         return;
  398.     }
  399.     n = 0;
  400.     XtSetArg(args[n], XmNdeleteResponse,    XmDO_NOTHING);        n++;
  401.     XtSetArg(args[n], XmNiconic,        False);            n++;
  402.     shell = XtAppCreateShell("Form Editor", "Grok",
  403.             applicationShellWidgetClass, display, args, n);
  404.     set_icon(shell, 1);
  405.  
  406.     cform = XtCreateWidget("editform", xmFormWidgetClass,
  407.             shell, NULL, 0);
  408.     XtAddCallback(cform, XmNhelpCallback,
  409.             (XtCallbackProc)help_callback, (XtPointer)"edit");
  410.  
  411.     for (len=0, tp=template; tp->type; tp++)
  412.         if (tp->type == 'L') {
  413.             n = strlen_in_pixels(tp->text, FONT_HELV_S);
  414.             if (n > len)
  415.                 len = n;
  416.         }
  417.     for (t=0, tp=template; tp->type; tp++, t++) {
  418.         n = 0;
  419.         switch(tp->type) {
  420.           case ']':
  421.             XtManageChild(cform);
  422.             XtManageChild(scroll);
  423.             cform = outerform;
  424.             prev  = scroll;
  425.             continue;
  426.           case '}':
  427.             XtManageChild(cform);
  428.             XtManageChild(chart);
  429.             cform = innerform;
  430.             prev  = chart;
  431.             continue;
  432.           case 'L':
  433.           case '-':
  434.           case '[':
  435.           case '{':
  436.             top  = prevline = prev;
  437.             left = 0;
  438.             break;
  439.           default:
  440.             top  = prevline;
  441.             left = prev;
  442.         }
  443.         if (top) {
  444.            XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);  n++;
  445.            XtSetArg(args[n], XmNtopWidget,    top);           n++;
  446.         } else {
  447.            XtSetArg(args[n], XmNtopAttachment,    XmATTACH_FORM);       n++;
  448.         }
  449.         if (left) {
  450.            XtSetArg(args[n], XmNleftAttachment,    XmATTACH_WIDGET);  n++;
  451.            XtSetArg(args[n], XmNleftWidget,    left);           n++;
  452.            XtSetArg(args[n], XmNleftOffset,    8);           n++;
  453.         } else {
  454.            XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);       n++;
  455.            XtSetArg(args[n], XmNleftOffset,    8);           n++;
  456.         }
  457.         if (tp->type == 'T' || tp->type == 't' || tp->type == 'L') {
  458.            XtSetArg(args[n], XmNalignment,  XmALIGNMENT_BEGINNING);n++;
  459.         }
  460.         if (tp->type == 'T' || tp->type == '-') {
  461.            XtSetArg(args[n], XmNrightAttachment,XmATTACH_FORM);       n++;
  462.         }
  463.         if (tp->type == 'B') {
  464.            XtSetArg(args[n], XmNwidth,        90);           n++;
  465.         }
  466.         if (tp->type == 't') {
  467.            XtSetArg(args[n], XmNwidth,        100);           n++;
  468.            XtSetArg(args[n], XmNtopOffset,    2);           n++;
  469.         }
  470.         if (tp->code == 0x101 && !new) {
  471.            XtSetArg(args[n], XmNrightOffset,    8);           n++;
  472.            XtSetArg(args[n], XmNtopOffset,    2);           n++;
  473.            XtSetArg(args[n], XmNeditable,    FALSE);           n++;
  474.         } else if (tp->type == 'T' || tp->type == 't') {
  475.            XtSetArg(args[n], XmNrightOffset,    8);           n++;
  476.            XtSetArg(args[n], XmNbackground,   color[COL_TEXTBACK]);n++;
  477.            XtSetArg(args[n], XmNtopOffset,    2);           n++;
  478.         } else {
  479.            XtSetArg(args[n], XmNtopOffset,    6);           n++;
  480.            XtSetArg(args[n], XmNhighlightThickness, 1);           n++;
  481.         }
  482.         if (tp->type == 'L') {
  483.            XtSetArg(args[n], XmNwidth,        len+4);           n++;
  484.         }
  485.         if (tp->type == 'F' || tp->type == 'R') {
  486.            XtSetArg(args[n], XmNpacking,    XmPACK_TIGHT);       n++;
  487.            XtSetArg(args[n], XmNspacing,    4);           n++;
  488.         }
  489.         if (tp->type == 'f' || tp->type == 'r') {
  490.            XtSetArg(args[n], XmNfillOnSelect,    True);           n++;
  491.            XtSetArg(args[n], XmNselectColor,    color[COL_TOGGLE]);n++;
  492.            cback = XmNvalueChangedCallback;
  493.         } else
  494.            cback = XmNactivateCallback;
  495.         if (tp->type == 'f') {
  496.            XtSetArg(args[n], XmNindicatorType,    XmN_OF_MANY);       n++;
  497.         }
  498.         if (tp->type == 'r') {
  499.            XtSetArg(args[n], XmNindicatorType,    XmONE_OF_MANY);       n++;
  500.         }
  501.         if (tp->type == '[') {
  502.            XtSetArg(args[n], XmNscrollingPolicy,XmVARIABLE);       n++;
  503.            XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM);   n++;
  504.            XtSetArg(args[n], XmNbottomOffset,    8);           n++;
  505.            XtSetArg(args[n], XmNrightAttachment,XmATTACH_FORM);       n++;
  506.            XtSetArg(args[n], XmNrightOffset,    8);           n++;
  507.            XtSetArg(args[n], XmNheight,        480);           n++;
  508.         }
  509.         if (tp->type == '{') {
  510.            XtSetArg(args[n], XmNshadowType,    XmSHADOW_IN);       n++;
  511.            XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM);   n++;
  512.            XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM);    n++;
  513.            XtSetArg(args[n], XmNrightAttachment,XmATTACH_FORM);       n++;
  514.            XtSetArg(args[n], XmNrightOffset,    8);           n++;
  515.            XtSetArg(args[n], XmNleftOffset,    8);           n++;
  516.            XtSetArg(args[n], XmNbottomOffset,    8);           n++;
  517.         }
  518.         XtSetArg(args[n],    XmNfontList, fontlist[FONT_HELV_S]);  n++;
  519.  
  520.         switch(tp->type) {
  521.           case '-': class = xmSeparatorWidgetClass;        break;
  522.           case 'L': class = xmLabelWidgetClass;            break;
  523.           case 'l': class = xmLabelWidgetClass;            break;
  524.           case 't': class = xmTextWidgetClass;            break;
  525.           case 'T': class = xmTextWidgetClass;            break;
  526.           case 'R': class = xmRowColumnWidgetClass;        break;
  527.           case 'F': class = xmRowColumnWidgetClass;        break;
  528.           case 'f': class = xmToggleButtonWidgetClass;        break;
  529.           case 'r': class = xmToggleButtonWidgetClass;        break;
  530.           case '[': class = xmScrolledWindowWidgetClass;    break;
  531.           case '{': class = xmFrameWidgetClass;            break;
  532.           case 'B': class = xmPushButtonWidgetClass;        break;
  533.         }
  534.         tp->widget =
  535.         prev = XtCreateManagedWidget(tp->text, class, cform, args, n);
  536.         if (tp->code && !strchr("RFl", tp->type))
  537.             XtAddCallback(prev, cback, (XtCallbackProc)
  538.                     formedit_callback, (XtPointer)t);
  539.         if (tp->help)
  540.             XtAddCallback(prev, XmNhelpCallback, (XtCallbackProc)
  541.                     help_callback, (XtPointer)tp->help);
  542.         if (tp->type == '[') {
  543.             XtUnmanageChild(prev);
  544.             outerform = cform;
  545.             scroll = prev;
  546.             prev   = 0;
  547.             cform  = XtCreateWidget("escrform",
  548.                     xmFormWidgetClass, scroll, NULL, 0);
  549.         }
  550.         if (tp->type == '{') {
  551.             XtUnmanageChild(prev);
  552.             innerform = cform;
  553.             chart  = prev;
  554.             prev   = 0;
  555.             cform  = XtCreateWidget("chartform",
  556.                     xmFormWidgetClass, chart, NULL, 0);
  557.         }
  558.     }
  559.     XtManageChild(cform);
  560.     sensitize_formedit();
  561.     fillout_formedit();
  562.     XtPopup(shell, XtGrabNone);
  563.     closewindow = XmInternAtom(display, "WM_DELETE_WINDOW", False);
  564.     XmAddWMProtocolCallback(shell, closewindow,
  565.             (XtCallbackProc)formedit_callback, (XtPointer)0);
  566.     have_shell = TRUE;
  567. }
  568.  
  569.  
  570. /*-------------------------------------------------- menu printing ----------*/
  571. /*
  572.  * sensitize only those items in the form window that are needed by the
  573.  * current type. The procedural edit button is an exception, its
  574.  * sensitivity is determined as a special case because it doesn't
  575.  * depend on the item type.
  576.  */
  577.  
  578. void sensitize_formedit(void)
  579. {
  580.     Arg            args;
  581.     struct _template    *tp;
  582.     int            mask;
  583.  
  584.     mask = curr_item >= form->nitems
  585.                 ? 1 << IT_NULL
  586.                 : 1 << form->items[curr_item]->type;
  587.     for (tp=template; tp->type; tp++) 
  588.         if (tp->sensitive) {
  589.             XtSetArg(args, XmNsensitive,
  590.                     tp->code == 'B' && !form->proc ? 0 :
  591.                     tp->sensitive & mask ? True : False);
  592.             XtSetValues(tp->widget, &args, 1);
  593.         }
  594. }
  595.  
  596.  
  597. /*
  598.  * fillout_formedit draws all the current item's values into the form
  599.  * definition window.
  600.  * fillout_formedit_widget_by_code draws a single value into the form.
  601.  * The code is searched for in the field list; see struct _template.
  602.  * This is somewhat inefficient, an index into template[] would be
  603.  * faster but would be guaranteed to get out of sync if template[] is
  604.  * changed.
  605.  * fillout_formedit_widget also draws a single field, but gets a pointer
  606.  * to the right template[] line. The previous two routines use this.
  607.  */
  608.  
  609. static void fillout_formedit_widget(struct _template *);
  610.  
  611. void fillout_formedit(void)
  612. {
  613.     struct _template    *tp;
  614.  
  615.     for (tp=template; tp->type; tp++)
  616.         fillout_formedit_widget(tp);
  617. }
  618.  
  619.  
  620. void fillout_formedit_widget_by_code(
  621.     int            code)
  622. {
  623.     struct _template    *tp;
  624.  
  625.     for (tp=template; tp->type; tp++)
  626.         if (tp->code == code) {
  627.             fillout_formedit_widget(tp);
  628.             break;
  629.         }
  630. }
  631.  
  632.  
  633. static void fillout_formedit_widget(
  634.     struct _template    *tp)
  635. {
  636.     register ITEM        *item;
  637.     register CHART        *chart;
  638.     CHART            nullchart;
  639.     Widget            w = tp->widget;
  640.  
  641.     if (tp->code < 0x100 || tp->code > 0x107) {
  642.         if (!form->items || curr_item >= form->nitems ||
  643.             !(tp->sensitive & (1 << form->items[curr_item]->type))) {
  644.             if (tp->type == 'T' || tp->type == 't')
  645.                 print_text_button_s(w, "");
  646.             return;
  647.         }
  648.         item  = form->items[curr_item];
  649.         chart = &item->ch_comp[item->ch_curr];
  650.         if (!chart)
  651.             mybzero((void *)(chart = &nullchart), sizeof(CHART));
  652.     }
  653.     switch(tp->code) {
  654.       case 0x101: print_text_button_s(w, form->name);        break;
  655.       case 0x102: print_text_button_s(w, form->dbase);        break;
  656.       case 0x107: print_text_button_s(w, form->comment);        break;
  657.       case 0x103: print_text_button_s(w, to_octal(form->cdelim));    break;
  658.       case 0x104: set_toggle(w, form->rdonly);            break;
  659.       case 0x105: set_toggle(w, form->proc);
  660.               fillout_formedit_widget_by_code(0x106);        break;
  661.       case 0x106: XtVaSetValues(w, XmNsensitive, form->proc, 0);    break;
  662.  
  663.       case IT_LABEL:
  664.       case IT_PRINT:
  665.       case IT_INPUT:
  666.       case IT_TIME:
  667.       case IT_NOTE:
  668.       case IT_CHOICE:
  669.       case IT_FLAG:
  670.       case IT_BUTTON:
  671.       case IT_VIEW:
  672.       case IT_CHART:
  673.               set_toggle(w, item->type == tp->code);        break;
  674.  
  675.       case 0x210:
  676.       case 0x211:
  677.       case 0x212:
  678.       case 0x213:
  679.       case 0x214: set_toggle(w, item->labelfont == tp->code-0x210);    break;
  680.  
  681.       case 0x215:
  682.       case 0x216:
  683.       case 0x217:
  684.       case 0x218:
  685.       case 0x219: set_toggle(w, item->inputfont == tp->code-0x215);    break;
  686.  
  687.       case 0x20d: set_toggle(w, item->labeljust == J_LEFT);        break;
  688.       case 0x20e: set_toggle(w, item->labeljust == J_CENTER);    break;
  689.       case 0x20f: set_toggle(w, item->labeljust == J_RIGHT);    break;
  690.  
  691.       case 0x21b: set_toggle(w, item->inputjust == J_LEFT);        break;
  692.       case 0x21c: set_toggle(w, item->inputjust == J_CENTER);    break;
  693.       case 0x21d: set_toggle(w, item->inputjust == J_RIGHT);    break;
  694.  
  695.       case 0x200: set_toggle(w, item->search);            break;
  696.       case 0x201: set_toggle(w, item->rdonly);            break;
  697.       case 0x202: set_toggle(w, item->nosort);            break;
  698.       case 0x203: set_toggle(w, item->defsort);            break;
  699.       case 0x209: set_toggle(w, item->timefmt == T_DATE);        break;
  700.       case 0x20a: set_toggle(w, item->timefmt == T_TIME);        break;
  701.       case 0x20b: set_toggle(w, item->timefmt == T_DATETIME);    break;
  702.       case 0x20c: set_toggle(w, item->timefmt == T_DURATION);    break;
  703.  
  704.       case 0x21e: print_text_button(w, "%d", item->minlen);        break;
  705.       case 0x21f: print_text_button(w, "%d", item->maxlen);        break;
  706.       case 0x206: print_text_button(w, "%d", item->sumcol);        break;
  707.       case 0x207: print_text_button(w, "%d", item->sumwidth);    break;
  708.       case 0x205: print_text_button(w, "%d", item->column);        break;
  709.       case 0x204: print_text_button_s(w, item->name);        break;
  710.       case 0x208: print_text_button_s(w, item->flagcode);        break;
  711.       case 0x236: print_text_button_s(w, item->flagtext);        break;
  712.       case 0x21a: print_text_button_s(w, item->label);        break;
  713.       case 0x220: print_text_button_s(w, item->idefault);        break;
  714.       case 0x221: print_text_button_s(w, item->pattern);        break;
  715.  
  716.       case 0x222: print_text_button_s(w, item->gray_if);        break;
  717.       case 0x223: print_text_button_s(w, item->invisible_if);    break;
  718.       case 0x224: print_text_button_s(w, item->freeze_if);        break;
  719.       case 0x225: print_text_button_s(w, item->skip_if);        break;
  720.  
  721.       case 0x226: print_text_button_s(w, item->pressed);        break;
  722.       case 0x227: print_text_button_s(w, item->added);        break;
  723.  
  724.       case 0x280: print_text_button(w, "%g", item->ch_xmin);    break;
  725.       case 0x281: print_text_button(w, "%g", item->ch_xmax);    break;
  726.       case 0x282: print_text_button(w, "%g", item->ch_ymin);    break;
  727.       case 0x283: print_text_button(w, "%g", item->ch_ymax);    break;
  728.       case 0x284: print_text_button(w, "%g", item->ch_xgrid);    break;
  729.       case 0x285: print_text_button(w, "%g", item->ch_ygrid);    break;
  730.       case 0x286: print_text_button(w, "%g", item->ch_xsnap);    break;
  731.       case 0x287: print_text_button(w, "%g", item->ch_ysnap);    break;
  732.       case 0x288: print_text_button(w, "%g", item->ch_xlabel);    break;
  733.       case 0x28a: print_text_button(w, "%g", item->ch_ylabel);    break;
  734.       case 0x289: print_text_button_s(w, item->ch_xexpr);        break;
  735.       case 0x28b: print_text_button_s(w, item->ch_yexpr);        break;
  736.       case 0x28c: set_toggle(w, item->ch_xauto);            break;
  737.       case 0x28d: set_toggle(w, item->ch_yauto);            break;
  738.       case 0x294: print_button(w, item->ch_ncomp ? "%d of %d" : "none",
  739.                     item->ch_curr+1, item->ch_ncomp);    break;
  740.  
  741.       case 0x301: set_toggle(w, chart->line);            break;
  742.       case 0x302: set_toggle(w, chart->xfat);            break;
  743.       case 0x303: set_toggle(w, chart->yfat);            break;
  744.       case 0x304: print_text_button_s(w, chart->excl_if);        break;
  745.       case 0x305: print_text_button_s(w, chart->color);        break;
  746.       case 0x306: print_text_button_s(w, chart->label);        break;
  747.  
  748.       case 0x310: set_toggle(w, chart->value[0].mode == CC_NEXT);    break;
  749.       case 0x311: set_toggle(w, chart->value[0].mode == CC_SAME);    break;
  750.       case 0x312: set_toggle(w, chart->value[0].mode == CC_EXPR);    break;
  751.       case 0x313: set_toggle(w, chart->value[0].mode == CC_DRAG);    break;
  752.       case 0x314: print_text_button_s(w, chart->value[0].expr);    break;
  753.       case 0x315: print_text_button(w, "%d", chart->value[0].field);break;
  754.       case 0x316: print_text_button(w, "%g", chart->value[0].mul);    break;
  755.       case 0x317: print_text_button(w, "%g", chart->value[0].add);    break;
  756.  
  757.       case 0x320: set_toggle(w, chart->value[1].mode == CC_NEXT);    break;
  758.       case 0x321: set_toggle(w, chart->value[1].mode == CC_SAME);    break;
  759.       case 0x322: set_toggle(w, chart->value[1].mode == CC_EXPR);    break;
  760.       case 0x323: set_toggle(w, chart->value[1].mode == CC_DRAG);    break;
  761.       case 0x324: print_text_button_s(w, chart->value[1].expr);    break;
  762.       case 0x325: print_text_button(w, "%d", chart->value[1].field);break;
  763.       case 0x326: print_text_button(w, "%g", chart->value[1].mul);    break;
  764.       case 0x327: print_text_button(w, "%g", chart->value[1].add);    break;
  765.  
  766.       case 0x330: set_toggle(w, chart->value[2].mode == CC_NEXT);    break;
  767.       case 0x331: set_toggle(w, chart->value[2].mode == CC_SAME);    break;
  768.       case 0x332: set_toggle(w, chart->value[2].mode == CC_EXPR);    break;
  769.       case 0x333: set_toggle(w, chart->value[2].mode == CC_DRAG);    break;
  770.       case 0x334: print_text_button_s(w, chart->value[2].expr);    break;
  771.       case 0x335: print_text_button(w, "%d", chart->value[2].field);break;
  772.       case 0x336: print_text_button(w, "%g", chart->value[2].mul);    break;
  773.       case 0x337: print_text_button(w, "%g", chart->value[2].add);    break;
  774.  
  775.       case 0x340: set_toggle(w, chart->value[3].mode == CC_NEXT);    break;
  776.       case 0x341: set_toggle(w, chart->value[3].mode == CC_SAME);    break;
  777.       case 0x342: set_toggle(w, chart->value[3].mode == CC_EXPR);    break;
  778.       case 0x343: set_toggle(w, chart->value[3].mode == CC_DRAG);    break;
  779.       case 0x344: print_text_button_s(w, chart->value[3].expr);    break;
  780.       case 0x345: print_text_button(w, "%d", chart->value[3].field);break;
  781.       case 0x346: print_text_button(w, "%g", chart->value[3].mul);    break;
  782.       case 0x347: print_text_button(w, "%g", chart->value[3].add);    break;
  783.  
  784.       case 0x234: print_text_button_s(w, item->database);        break;
  785.       case 0x235: print_text_button_s(w, item->query);        break;
  786.       case 0x231: set_toggle(w, item->qsummary);            break;
  787.       case 0x232: set_toggle(w, item->qfirst);            break;
  788.       case 0x233: set_toggle(w, item->qlast);            break;
  789.     }
  790. }
  791.  
  792.  
  793. /*-------------------------------------------------- button callbacks -------*/
  794. /*
  795.  * some item in one of the menu bar pulldowns was pressed. All of these
  796.  * routines are direct X callbacks.
  797.  */
  798.  
  799. /*ARGSUSED*/
  800. static void formedit_callback(
  801.     Widget                widget,
  802.     int                indx,
  803.     XmToggleButtonCallbackStruct    *data)
  804. {
  805.     switch(readback_item(indx)) {
  806.       case 1:
  807.         fillout_formedit_widget(&template[indx]);
  808.         if (form->items && curr_item < form->nitems)
  809.             redraw_canvas_item(form->items[curr_item]);
  810.         break;
  811.       case 2:
  812.         sensitize_formedit();
  813.         fillout_formedit();
  814.         redraw_canvas();
  815.     }
  816. }
  817.  
  818.  
  819. /*
  820.  * read back all text widgets. This must be done before a new item is
  821.  * selected or added, because we'll never see new text in text buttons
  822.  * unless the user explicitly pressed Return on them.
  823.  */
  824.  
  825. void readback_formedit(void)
  826. {
  827.     struct _template    *tp;
  828.     int            t;
  829.  
  830.     if (curr_item < form->nitems)
  831.         for (t=0, tp=template; tp->type; tp++, t++)
  832.             if (tp->type == 'T' || tp->type == 't')
  833.                 (void)readback_item(t);
  834. }
  835.  
  836.  
  837. /*
  838.  * do the operation requested by the widget: execute a function, or read
  839.  * back a value into the form or current item. Return 0 if no canvas redraw
  840.  * is required, 1 if the current item on the canvas must be redrawn, and 2
  841.  * if the entire canvas must be redrawn.
  842.  */
  843.  
  844. static void cancel_callback(void)
  845. {
  846.     destroy_formedit_window();
  847.     destroy_canvas_window();
  848.     destroy_query_window();
  849.     form_delete(form);
  850.     free((void *)form);
  851.     form = 0;
  852. }
  853.  
  854. static int readback_item(
  855.     int            indx)
  856. {
  857.     struct _template    *tp = &template[indx];
  858.     register ITEM        *item = 0, *ip;
  859.     register CHART        *chart = 0;
  860.     Widget            w = tp->widget;
  861.     int            code, i;
  862.     BOOL            all = FALSE; /* redraw oll or one? */
  863.  
  864.     if (curr_item < form->nitems) {
  865.         item  = form->items[curr_item];
  866.         chart = &item->ch_comp[item->ch_curr];
  867.     }
  868.     if (!chart && (tp->code & 0x300) == 0x300)
  869.         return(0);
  870.  
  871.     switch(tp->code) {
  872.       case 0x101: (void)read_text_button_noblanks(w, &form->name);
  873.               if (form->name && !form->dbase) {
  874.                 form->dbase = mystrdup(form->name);
  875.                 fillout_formedit_widget_by_code(0x102);
  876.               }
  877.               break;
  878.  
  879.       case 0x102: (void)read_text_button_noblanks(w, &form->dbase);    break;
  880.       case 0x107: (void)read_text_button(w, &form->comment);    break;
  881.       case 0x103: form->cdelim=to_ascii(read_text_button(w,0),':');    break;
  882.       case 0x104: form->rdonly     ^= TRUE;                break;
  883.       case 0x105: form->proc       ^= TRUE; sensitize_formedit();    break;
  884.       case 0x106: form_edit_script(form, w, form->dbase);        break;
  885.  
  886.       case 0x112: readback_formedit();
  887.               item_deselect(form);
  888.               (void)item_create(form, curr_item);
  889.               form->items[curr_item]->selected = TRUE;
  890.               all = TRUE;
  891.               break;
  892.  
  893.       case 0x113: item_deselect(form);
  894.               item_delete(form, curr_item);
  895.               if (curr_item >= form->nitems)
  896.                 if (curr_item)
  897.                     curr_item--;
  898.                 else
  899.                     item_deselect(form);
  900.                all = TRUE;
  901.               break;
  902.  
  903.       case 0x10b: create_edit_popup("Card Help Editor",
  904.                      &form->help, FALSE, "fe_help");
  905.               break;
  906.  
  907.       case 0x10c: create_query_window(form);
  908.               break;
  909.  
  910.       case 0x10d: if (!verify_form(form, &i, shell) && i < form->nitems) {
  911.                 item_deselect(form);
  912.                 curr_item = i;
  913.                 form->items[i]->selected = TRUE;
  914.                 redraw_canvas_item(form->items[i]);
  915.                 fillout_formedit();
  916.                 sensitize_formedit();
  917.               }
  918.               break;
  919.  
  920.       case 0x10e: create_card_menu(form, 0, 0);
  921.               break;
  922.  
  923.       case 0x10f: help_callback(shell, "edit");
  924.                return(0);
  925.  
  926.       case 0x111: readback_formedit();
  927.               if (!verify_form(form, &i, shell)) {
  928.                 if (i < form->nitems) {
  929.                     item_deselect(form);
  930.                     curr_item = i;
  931.                     form->items[i]->selected = TRUE;
  932.                     redraw_canvas_item(form->items[i]);
  933.                     fillout_formedit();
  934.                     sensitize_formedit();
  935.                 }
  936.                 return(0);
  937.               }
  938.                 destroy_formedit_window();
  939.               destroy_canvas_window();
  940.               destroy_query_window();
  941.               form_sort(form);
  942.               if (!write_form(form))
  943.                 return(0);
  944.               switch_form(form->name);
  945.               form_delete(form);
  946.               free((void *)form);
  947.               form = 0;
  948.                return(0);
  949.  
  950.       case 0x110: create_query_popup(shell, cancel_callback,
  951.                 "form_cancel", "Ok to discard changes?");
  952.                return(0);
  953.  
  954.       case IT_LABEL:
  955.       case IT_PRINT:
  956.       case IT_INPUT:
  957.       case IT_TIME:
  958.       case IT_NOTE:
  959.       case IT_CHOICE:
  960.       case IT_FLAG:
  961.       case IT_BUTTON:
  962.       case IT_VIEW:
  963.       case IT_CHART:
  964.                item->type = tp->code;
  965.               all = TRUE;
  966.               break;
  967.  
  968.       case 0x202: item->nosort ^= TRUE;
  969.               if (item->name)
  970.                 for (i=0; i < form->nitems; i++) {
  971.                     ip = form->items[i];
  972.                     if (ip->name &&
  973.                         !strcmp(item->name, ip->name))
  974.                         ip->nosort = item->nosort;
  975.                 }
  976.               break;
  977.  
  978.       case 0x203: item->defsort ^= TRUE;
  979.               if (item->name)
  980.                 for (i=0; i < form->nitems; i++)
  981.                     if (i != curr_item) {
  982.                     ip = form->items[i];
  983.                     ip->defsort = !strcmp(item->name,
  984.                          ip->name) ? item->defsort : FALSE;
  985.                 }
  986.               break;
  987.  
  988.       case 0x210:
  989.       case 0x211:
  990.       case 0x212:
  991.       case 0x213:
  992.       case 0x214: item->labelfont = tp->code - 0x210;
  993.               for (code=0x210; code <= 0x214; code++)
  994.                 fillout_formedit_widget_by_code(code);
  995.               all = TRUE;
  996.               break;
  997.  
  998.       case 0x215:
  999.       case 0x216:
  1000.       case 0x217:
  1001.       case 0x218:
  1002.       case 0x219: item->inputfont = tp->code - 0x215;
  1003.               for (code=0x215; code <= 0x219; code++)
  1004.                 fillout_formedit_widget_by_code(code);
  1005.               all = TRUE;
  1006.               break;
  1007.  
  1008.       case 0x20d: item->labeljust = J_LEFT;
  1009.               fillout_formedit_widget_by_code(0x20e);
  1010.               fillout_formedit_widget_by_code(0x20f);        break;
  1011.       case 0x20e: item->labeljust = J_CENTER;
  1012.               fillout_formedit_widget_by_code(0x20d);
  1013.               fillout_formedit_widget_by_code(0x20f);        break;
  1014.       case 0x20f: item->labeljust = J_RIGHT;
  1015.               fillout_formedit_widget_by_code(0x20d);
  1016.               fillout_formedit_widget_by_code(0x20e);        break;
  1017.  
  1018.       case 0x21b: item->inputjust = J_LEFT;
  1019.               fillout_formedit_widget_by_code(0x21c);
  1020.               fillout_formedit_widget_by_code(0x21d);        break;
  1021.       case 0x21c: item->inputjust = J_CENTER;
  1022.               fillout_formedit_widget_by_code(0x21b);
  1023.               fillout_formedit_widget_by_code(0x21d);        break;
  1024.       case 0x21d: item->inputjust = J_RIGHT;
  1025.               fillout_formedit_widget_by_code(0x21b);
  1026.               fillout_formedit_widget_by_code(0x21c);        break;
  1027.  
  1028.       case 0x200: item->search ^= TRUE;                break;
  1029.       case 0x201: item->rdonly ^= TRUE;                break;
  1030.       case 0x209: item->timefmt = T_DATE;        all = TRUE;    break;
  1031.       case 0x20a: item->timefmt = T_TIME;        all = TRUE;    break;
  1032.       case 0x20b: item->timefmt = T_DATETIME;    all = TRUE;    break;
  1033.       case 0x20c: item->timefmt = T_DURATION;    all = TRUE;    break;
  1034.  
  1035.       case 0x21e: item->minlen   = atoi(read_text_button(w, 0));    break;
  1036.       case 0x21f: item->maxlen   = atoi(read_text_button(w, 0));    break;
  1037.       case 0x206: item->sumcol   = atoi(read_text_button(w, 0));    break;
  1038.       case 0x207: item->sumwidth = atoi(read_text_button(w, 0));    break;
  1039.       case 0x205: item->column   = atoi(read_text_button(w, 0));    break;
  1040.       case 0x204: (void)read_text_button(w, &item->name);        break;
  1041.       case 0x208: (void)read_text_button(w, &item->flagcode);    break;
  1042.       case 0x236: (void)read_text_button(w, &item->flagtext);    break;
  1043.       case 0x21a: (void)read_text_button(w, &item->label);        break;
  1044.       case 0x220: (void)read_text_button(w, &item->idefault);    break;
  1045.       case 0x221: (void)read_text_button(w, &item->pattern);    break;
  1046.  
  1047.       case 0x222: (void)read_text_button(w, &item->gray_if);    break;
  1048.       case 0x223: (void)read_text_button(w, &item->invisible_if);    break;
  1049.       case 0x224: (void)read_text_button(w, &item->freeze_if);    break;
  1050.       case 0x225: (void)read_text_button(w, &item->skip_if);    break;
  1051.  
  1052.       case 0x226: (void)read_text_button(w, &item->pressed);    break;
  1053.       case 0x227: (void)read_text_button(w, &item->added);        break;
  1054.  
  1055.       case 0x280: item->ch_xmin   = atof(read_text_button(w, 0));    break;
  1056.       case 0x281: item->ch_xmax   = atof(read_text_button(w, 0));    break;
  1057.       case 0x282: item->ch_ymin   = atof(read_text_button(w, 0));    break;
  1058.       case 0x283: item->ch_ymax   = atof(read_text_button(w, 0));    break;
  1059.       case 0x284: item->ch_xgrid  = atof(read_text_button(w, 0));    break;
  1060.       case 0x285: item->ch_ygrid  = atof(read_text_button(w, 0));    break;
  1061.       case 0x286: item->ch_xsnap  = atof(read_text_button(w, 0));    break;
  1062.       case 0x287: item->ch_ysnap  = atof(read_text_button(w, 0));    break;
  1063.       case 0x288: item->ch_xlabel = atof(read_text_button(w, 0));    break;
  1064.       case 0x28a: item->ch_ylabel = atof(read_text_button(w, 0));    break;
  1065.       case 0x289: (void)read_text_button(w, &item->ch_xexpr);    break;
  1066.       case 0x28b: (void)read_text_button(w, &item->ch_yexpr);    break;
  1067.       case 0x28c: item->ch_xauto ^= TRUE;                break;
  1068.       case 0x28d: item->ch_yauto ^= TRUE;                break;
  1069.  
  1070.       case 0x290: add_chart_component(item); all = TRUE;        break;
  1071.       case 0x291: del_chart_component(item); all = TRUE;        break;
  1072.       case 0x292: if (item->ch_curr) item->ch_curr--; all = TRUE;    break;
  1073.       case 0x293: if (item->ch_curr < item->ch_ncomp-1) item->ch_curr++;
  1074.               all = TRUE;                    break;
  1075.  
  1076.       case 0x301: chart->line ^= TRUE;                break;
  1077.       case 0x302: chart->xfat ^= TRUE;                break;
  1078.       case 0x303: chart->yfat ^= TRUE;                break;
  1079.       case 0x304: (void)read_text_button(w, &chart->excl_if);    break;
  1080.       case 0x305: (void)read_text_button(w, &chart->color);        break;
  1081.       case 0x306: (void)read_text_button(w, &chart->label);        break;
  1082.  
  1083.       case 0x310: chart->value[0].mode = CC_NEXT;            break;
  1084.       case 0x311: chart->value[0].mode = CC_SAME;            break;
  1085.       case 0x312: chart->value[0].mode = CC_EXPR;            break;
  1086.       case 0x313: chart->value[0].mode = CC_DRAG;            break;
  1087.       case 0x314: (void)read_text_button(w, &chart->value[0].expr);    break;
  1088.       case 0x315: chart->value[0].field=atof(read_text_button(w,0));break;
  1089.       case 0x316: chart->value[0].mul= atof(read_text_button(w, 0));break;
  1090.       case 0x317: chart->value[0].add= atof(read_text_button(w, 0));break;
  1091.  
  1092.       case 0x320: chart->value[1].mode = CC_NEXT;            break;
  1093.       case 0x321: chart->value[1].mode = CC_SAME;            break;
  1094.       case 0x322: chart->value[1].mode = CC_EXPR;            break;
  1095.       case 0x323: chart->value[1].mode = CC_DRAG;            break;
  1096.       case 0x324: (void)read_text_button(w, &chart->value[1].expr);    break;
  1097.       case 0x325: chart->value[1].field=atof(read_text_button(w,0));break;
  1098.       case 0x326: chart->value[1].mul= atof(read_text_button(w, 0));break;
  1099.       case 0x327: chart->value[1].add= atof(read_text_button(w, 0));break;
  1100.  
  1101.       case 0x330: chart->value[2].mode = CC_NEXT;            break;
  1102.       case 0x331: chart->value[2].mode = CC_SAME;            break;
  1103.       case 0x332: chart->value[2].mode = CC_EXPR;            break;
  1104.       case 0x333: chart->value[2].mode = CC_DRAG;            break;
  1105.       case 0x334: (void)read_text_button(w, &chart->value[2].expr);    break;
  1106.       case 0x335: chart->value[2].field=atof(read_text_button(w,0));break;
  1107.       case 0x336: chart->value[2].mul= atof(read_text_button(w, 0));break;
  1108.       case 0x337: chart->value[2].add= atof(read_text_button(w, 0));break;
  1109.  
  1110.       case 0x340: chart->value[3].mode = CC_NEXT;            break;
  1111.       case 0x341: chart->value[3].mode = CC_SAME;            break;
  1112.       case 0x342: chart->value[3].mode = CC_EXPR;            break;
  1113.       case 0x343: chart->value[3].mode = CC_DRAG;            break;
  1114.       case 0x344: (void)read_text_button(w, &chart->value[3].expr);    break;
  1115.       case 0x345: chart->value[3].field=atof(read_text_button(w,0));break;
  1116.       case 0x346: chart->value[3].mul= atof(read_text_button(w, 0));break;
  1117.       case 0x347: chart->value[3].add= atof(read_text_button(w, 0));break;
  1118.  
  1119.       case 0x234: (void)read_text_button(w, &item->database);    break;
  1120.       case 0x235: (void)read_text_button(w, &item->query);        break;
  1121.       case 0x231: item->qsummary ^= TRUE;                break;
  1122.       case 0x232: item->qfirst   ^= TRUE;
  1123.                item->qlast     = FALSE;
  1124.               fillout_formedit_widget_by_code(0x233);        break;
  1125.       case 0x233: item->qlast    ^= TRUE;
  1126.                item->qfirst    = FALSE;
  1127.               fillout_formedit_widget_by_code(0x232);        break;
  1128.     }
  1129.  
  1130.     /*
  1131.      * the chart choice buttons are widely separated and must be handled
  1132.      * by hand here, to make sure only one of each group is enabled.
  1133.      */
  1134.     i = tp->code & 0x00f;
  1135.     if (tp->code >= 0x310 && tp->code <= 0x3ff && i < 4) {
  1136.         i = tp->code & 0x3f0;
  1137.         fillout_formedit_widget_by_code(i + 0);
  1138.         fillout_formedit_widget_by_code(i + 1);
  1139.         fillout_formedit_widget_by_code(i + 2);
  1140.         fillout_formedit_widget_by_code(i + 3);
  1141.     }
  1142.  
  1143.     /*
  1144.      * if a choice item is modified, modify all other choice items with
  1145.      * the same name too.
  1146.      */
  1147.     if (item && item->name && item->type == IT_CHOICE)
  1148.         for (i=0; i < form->nitems; i++) {
  1149.             ip = form->items[i];
  1150.             if (i != curr_item && ip->type == IT_CHOICE
  1151.                        && ip->name
  1152.                        && !strcmp(ip->name, item->name)) {
  1153.                 ip->column   = item->column;
  1154.                 ip->search   = item->search;
  1155.                 ip->rdonly   = item->rdonly;
  1156.                 ip->nosort   = item->nosort;
  1157.                 ip->defsort  = item->defsort;
  1158.                   ip->sumcol   = item->sumcol;
  1159.                 ip->sumwidth = item->sumwidth;
  1160.                 ip->column   = item->column;
  1161.                 if (item->idefault) {
  1162.                     if (ip->idefault)
  1163.                         free(ip->idefault);
  1164.                       ip->idefault =mystrdup(item->idefault);
  1165.                 }
  1166.                 redraw_canvas_item(ip);
  1167.             }
  1168.         }
  1169.     return(all ? 2 : 1);
  1170. }
  1171.